package org.dfl.plugin.dialogs;

import java.util.HashMap;
import java.util.Map;

import org.dfl.core.data.types.Type;
import org.dfl.core.data.types.TypeManager;
import org.dfl.core.model.Edge;
import org.dfl.messages.Messages;
import org.dfl.plugin.editor.model.ConnectionModelElement;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

/**
 * dialog to change edge properties
 * @author Piotr Wlodarczyk
 *
 */
public class EdgePropertiesDialog extends BaseDialog {
	protected Combo propertiesCombo;
	protected ConnectionModelElement connection;
	protected Map<Integer,Integer> selectionMap = new HashMap<Integer,Integer>();
	
	public static final int PROP_NONE = 0;
	public static final int PROP_TRUE = 1;
	public static final int PROP_FALSE = 2;
	public static final int PROP_EMPTY = 3;
	public static final int PROP_NOTEMPTY = 4;

	private boolean okButtonClicked = false;
	private Listener okListener;
	
	public EdgePropertiesDialog(ConnectionModelElement connection) {
		super();
		this.connection = connection;
	}

	@Override
	protected Shell getNewShell() {
		Shell shell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);

		GridLayout dialogShellLayout = new GridLayout();
		dialogShellLayout.makeColumnsEqualWidth = true;
		shell.setLayout(dialogShellLayout);
		shell.layout();
		shell.pack();
		shell.setSize(321, 119);
		shell.setText(Messages.EdgePropertiesDialog_edgeProp);
		
		return shell;
	}

	@Override
	protected void init(final Shell dialogShell) {
		okListener = new Listener(){
			public void handleEvent(Event arg0) {
				if(validate()){
					okButtonClicked = true;
					finish();
					dialogShell.dispose();
				}
			}
		};
		{
			Composite propertiesComposite = new Composite(dialogShell, SWT.NONE);
			GridLayout propertiesLayout = new GridLayout();
			propertiesLayout.makeColumnsEqualWidth = true;
			GridData propertiesLData = new GridData();
			propertiesLData.widthHint = 243;
			propertiesLData.heightHint = 68;
			propertiesLData.grabExcessVerticalSpace = true;
			propertiesLData.grabExcessHorizontalSpace = true;
			propertiesLData.horizontalAlignment = GridData.CENTER;
			propertiesComposite.setLayoutData(propertiesLData);
			propertiesComposite.setLayout(propertiesLayout);
			{
				propertiesCombo = new Combo(propertiesComposite, SWT.READ_ONLY);
				GridData combo1LData = new GridData();
				combo1LData.widthHint = 205;
				combo1LData.heightHint = 21;
				propertiesCombo.setLayoutData(combo1LData);
				resetPropertiesCombo();
				addEnterKeyListener(propertiesCombo);
			}

			{
				Composite buttons = new Composite(dialogShell, SWT.NONE);
				GridLayout buttonsLayout = new GridLayout();
				buttonsLayout.makeColumnsEqualWidth = true;
				GridData buttonsLData = new GridData();
				buttonsLData.heightHint = 40;
				buttonsLData.grabExcessHorizontalSpace = true;
				buttonsLData.horizontalAlignment = GridData.FILL;
				buttons.setLayoutData(buttonsLData);
				buttons.setLayout(buttonsLayout);
				{
					Composite buttonsCentered = new Composite(buttons, SWT.NONE);
					RowLayout ButtonsCenteredLayout = new RowLayout(org.eclipse.swt.SWT.HORIZONTAL);
					GridData buttonsCenteredLData = new GridData();
					buttonsCenteredLData.widthHint = 198;
					buttonsCenteredLData.horizontalAlignment = GridData.CENTER;
					buttonsCenteredLData.grabExcessVerticalSpace = true;
					buttonsCenteredLData.grabExcessHorizontalSpace = true;
					buttonsCenteredLData.verticalAlignment = GridData.FILL;
					buttonsCentered.setLayoutData(buttonsCenteredLData);
					buttonsCentered.setLayout(ButtonsCenteredLayout);
					{
						Button okButton = new Button(buttonsCentered, SWT.PUSH | SWT.CENTER);
						RowData okButtonLData = new RowData();
						okButtonLData.width = 82;
						okButtonLData.height = 23;
						okButton.setLayoutData(okButtonLData);
						okButton.setText(Messages.EdgePropertiesDialog_ok);
						okButton.addListener(SWT.Selection,okListener);
					}
					{
						Button cancelButton = new Button(buttonsCentered, SWT.PUSH
							| SWT.CENTER);
						RowData cancelButtonLData = new RowData();
						cancelButtonLData.width = 88;
						cancelButtonLData.height = 23;
						cancelButton.setLayoutData(cancelButtonLData);
						cancelButton.setText(Messages.EdgePropertiesDialog_cancel);
						cancelButton.addListener(SWT.Selection,new Listener(){
							public void handleEvent(Event arg0) {
								dialogShell.dispose();
							}
						});
					}
				}
			}
		}
	}
	
	protected void addEnterKeyListener(Control control) {
		control.addListener(SWT.KeyDown, new Listener() {
		    public void handleEvent(Event event) {
		        if( event.keyCode == SWT.CR ) {
		        	okListener.handleEvent(event);
		        }
		    }
		});
	}
	
	protected boolean validate() {
		return true;
	}

	protected void finish() {
		switch (selectionMap.get(
				new Integer(propertiesCombo.getSelectionIndex())).intValue()) {
		case PROP_NONE:
			connection.setNoneProperty();
			break;
		case PROP_TRUE:
			connection.setTrueProperty();
			break;
		case PROP_FALSE:
			connection.setFalseProperty();
			break;
		case PROP_EMPTY:
			connection.setEmptyProperty();
			break;
		case PROP_NOTEMPTY:
			connection.setNotemptyProperty();
			break;
		}
	}
	
	protected void resetPropertiesCombo() {
		propertiesCombo.removeAll();
		propertiesCombo.add(Messages.EdgePropertiesDialog_none);
		selectionMap.put(new Integer(propertiesCombo.getItemCount()-1),new Integer(PROP_NONE));
		propertiesCombo.select(propertiesCombo.getItemCount()-1);
		
		Edge e = connection.getEdge();
		Type type = getType();
		if(TypeManager.isBooleanType(type) || TypeManager.isAnyType(type)){
			//add true property
			propertiesCombo.add(Messages.EdgePropertiesDialog_true);
			selectionMap.put(new Integer(propertiesCombo.getItemCount()-1),new Integer(PROP_TRUE));
			if(e.isNeededTrue()) propertiesCombo.select(propertiesCombo.getItemCount()-1);
			//add false property
			propertiesCombo.add(Messages.EdgePropertiesDialog_false);
			selectionMap.put(new Integer(propertiesCombo.getItemCount()-1),new Integer(PROP_FALSE));
			if(e.isNeededFalse()) propertiesCombo.select(propertiesCombo.getItemCount()-1);
		}
		if(TypeManager.isCollectionType(type) || TypeManager.isAnyType(type)){
//			add empty property
			propertiesCombo.add(Messages.EdgePropertiesDialog_empty);
			selectionMap.put(new Integer(propertiesCombo.getItemCount()-1),new Integer(PROP_EMPTY));
			if(e.isNeededEmpty()) propertiesCombo.select(propertiesCombo.getItemCount()-1);
//			add not empty property
			propertiesCombo.add(Messages.EdgePropertiesDialog_notEmpty);
			selectionMap.put(new Integer(propertiesCombo.getItemCount()-1),new Integer(PROP_NOTEMPTY));
			if(e.isNeededNotempty()) propertiesCombo.select(propertiesCombo.getItemCount()-1);
		}
	}

	protected Type getType() {
		boolean isTrueNew = connection.getEdge().isNeededTrue();
		boolean isFalseNew = connection.getEdge().isNeededFalse();
		boolean isEmptyNew = connection.getEdge().isNeededEmpty();
		boolean isNotEmptyNew = connection.getEdge().isNeededNotempty();
		connection.setNoneProperty();
		Type type = connection.getEdge().getTypeContainer().getType().getCopy();
		if (isEmptyNew)	connection.setEmptyProperty();
		if (isNotEmptyNew)	connection.setNotemptyProperty();
		if (isTrueNew)	connection.setTrueProperty();
		if (isFalseNew)	connection.setFalseProperty();
		return type;
	}

	public boolean isOkButtonClicked() {
		return okButtonClicked;
	}
	
	protected Edge getEdge(){
		return connection.getEdge();
	}
}
